package com.agent.vpsserver.modules.server.manager;

import cn.hutool.cache.Cache;
import cn.hutool.cache.impl.TimedCache;
import com.agent.vpsserver.common.enmus.EActiveSmsServiceType;
import com.agent.vpsserver.common.enmus.EResponseCode;
import com.agent.vpsserver.common.enmus.ESMSActivateClientStatus;
import com.agent.vpsserver.common.exception.BusinessException;
import com.agent.vpsserver.common.utils.common.IdUtils;
import com.agent.vpsserver.common.utils.mapping.BeansUtils;
import com.agent.vpsserver.modules.server.client.ActiveSmsClient;
import com.agent.vpsserver.modules.server.client.response.SMSActivateActivationResponse;
import com.agent.vpsserver.modules.server.client.response.SMSActivateGetCountryResponse;
import com.agent.vpsserver.modules.server.client.response.SMSActivateGetTopCountriesResponse;
import com.agent.vpsserver.modules.server.entity.pojo.SmsInfoDO;
import com.agent.vpsserver.modules.server.request.SmsGetContentRequest;
import com.agent.vpsserver.modules.server.request.SmsGetNumberRequest;
import com.agent.vpsserver.modules.server.request.SmsUpdateStatusRequest;
import com.agent.vpsserver.modules.server.response.*;
import com.agent.vpsserver.modules.server.service.SmsInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 用户账号信息(UserAccount)表服务实现类
 *
 * @author guochao
 * @since 2024-03-12 23:50:24
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SmsManager implements CommandLineRunner {
    private static Map<String, SmsGetBuyInfoResponse> COUNTRY_MAP = Collections.emptyMap();
    private static Cache<String, List<String>> OPERATOR_MAP = new TimedCache<>(1000 * 60 * 10);

    private final SmsInfoService smsInfoService;
    private final ActiveSmsClient activeSmsManager;

    /**
     * 生成
     *
     * @return
     */
    public SmsInfoGenerateResponse generate() {
        String uniqueCode = IdUtils.uuid();
        SmsInfoDO smsInfoDO = new SmsInfoDO();
        smsInfoDO.setUniqueCode(uniqueCode);
        smsInfoService.save(smsInfoDO);

        SmsInfoGenerateResponse response = new SmsInfoGenerateResponse();
        response.setUniqueCode(uniqueCode);
        return response;
    }

    /**
     * 获取手机号
     *
     * @param request 手机号唯一标识
     * @return
     */
    public SmsGetNumberResponse getNumber(SmsGetNumberRequest request) {
        synchronized (request.getUniqueCode()) {
            SmsInfoDO smsInfoDO = smsInfoService.getOne(new LambdaQueryWrapper<SmsInfoDO>()
                    .eq(SmsInfoDO::getUniqueCode, request.getUniqueCode()));
            if (smsInfoDO == null) {
                throw new BusinessException(EResponseCode.ILLEGAL_REQUEST);
            }
            String phone = smsInfoDO.getPhone();
            if (StringUtils.isBlank(phone)) {
                SMSActivateActivationResponse activateActivation = activeSmsManager.getNumber(request.getCountryId(), EActiveSmsServiceType.ESCAPE, request.getOperator());
                phone = String.valueOf(activateActivation.getPhoneNumber());
                String activationId = activateActivation.getActivationId();

                smsInfoDO.setActivationId(activationId);
                smsInfoDO.setCountryCode(activateActivation.getCountryCode());
                smsInfoDO.setPhone(phone);
                smsInfoService.updateById(smsInfoDO);
            }
            SmsGetNumberResponse response = new SmsGetNumberResponse();
            response.setPhone(phone);
            return response;
        }
    }

    /**
     * 获取短信内容
     *
     * @param request 手机号唯一标识
     * @return
     */
    public SmsGetContentResponse getContent(SmsGetContentRequest request) {
        synchronized (request.getUniqueCode()) {
            SmsInfoDO smsInfoDO = smsInfoService.getOne(new LambdaQueryWrapper<SmsInfoDO>()
                    .eq(SmsInfoDO::getUniqueCode, request.getUniqueCode()));
            if (smsInfoDO == null || StringUtils.isBlank(smsInfoDO.getPhone())) {
                throw new BusinessException(EResponseCode.ILLEGAL_REQUEST);
            }
            String code = smsInfoDO.getCode();
            if (StringUtils.isBlank(code)) {
                code = activeSmsManager.getStatus(smsInfoDO.getActivationId());
                if (StringUtils.isBlank(code)) {
                    throw new BusinessException("暂未收到验证码，请稍后重试");
                }
            }
            SmsGetContentResponse response = new SmsGetContentResponse();
            response.setCode(code);
            return response;
        }
    }

    public void updateStatus(SmsUpdateStatusRequest request) {
        SmsInfoDO smsInfoDO = smsInfoService.getById(request.getId());
        if (smsInfoDO == null) {
            throw new BusinessException("数据不存在");
        }
        // 短信状态 1、待使用 2、成功接受短信 3、已失效
        activeSmsManager.setStatus(smsInfoDO.getActivationId(), ESMSActivateClientStatus.CANCEL);
        smsInfoDO.setStatus(3);
        smsInfoService.updateById(smsInfoDO);
    }

    /**
     * 获取购买信息
     *
     * @return
     */
    public List<SmsGetBuyInfoResponse> getBuyInfo() {
        // 查询全部国家和运营商信息
        if (COUNTRY_MAP.isEmpty()) {
            this.initCache();
        }

        // 查询服务支持的国家
        Map<String, SMSActivateGetTopCountriesResponse> topCountriesMap = activeSmsManager.getTopCountriesByService(EActiveSmsServiceType.ESCAPE);
        List<SmsGetBuyInfoResponse> responseList = new ArrayList<>(topCountriesMap.size());
        for (String countryId : topCountriesMap.keySet()) {
            SmsGetBuyInfoResponse response = COUNTRY_MAP.get(countryId);
            if (response != null) {
                List<String> operator = OPERATOR_MAP.get(countryId);
                if (operator == null) {
                    // 查询运营商信息
                    operator = activeSmsManager.getOperator(countryId);
                    OPERATOR_MAP.put(countryId, operator);
                }
                if (CollectionUtils.isEmpty(operator)) {
                    continue;
                }
                response.setOperators(operator);
                responseList.add(response);
            }
        }
        return responseList;
    }

    @Override
    public void run(String... args) {
        this.initCache();
    }

    /**
     * 初始化缓存
     */
    private synchronized void initCache() {
        if (!COUNTRY_MAP.isEmpty()) {
            return;
        }
        Map<String, SMSActivateGetCountryResponse> countries = activeSmsManager.getCountry();
        HashMap<String, SmsGetBuyInfoResponse> countyMap = new HashMap<>();
        for (Map.Entry<String, SMSActivateGetCountryResponse> entry : countries.entrySet()) {
            String countryId = entry.getKey();
            SmsGetBuyInfoResponse buyInfoResponse = BeansUtils.map(entry.getValue(), SmsGetBuyInfoResponse.class);
            countyMap.put(countryId, buyInfoResponse);
        }
        COUNTRY_MAP = countyMap;
    }
}
